package com.wzdigit.wms.wms.service.core;

import com.alibaba.fastjson.JSON;
import com.wzdigit.mes.basic.api.BasicSimpleCodeRuleApi;
import com.wzdigit.wms.basic.domain.dtos.inventory.UpdateInventoryInputDto;
import com.wzdigit.wms.basic.domain.dtos.oqc.OqcInspDtlDto;
import com.wzdigit.wms.basic.domain.dtos.trsn.TrsnDtlDto;
import com.wzdigit.wms.basic.domain.dtos.trsn.TrsnDto;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.GoodsLog;
import com.wzdigit.wms.basic.domain.inventory.GoodsVersion;
import com.wzdigit.wms.basic.domain.inventory.InvTrans;
import com.wzdigit.wms.basic.domain.inventory.Lotno;
import com.wzdigit.wms.basic.domain.order.TrsnDtl;
import com.wzdigit.wms.basic.domain.order.TrsnDtlGoods;
import com.wzdigit.wms.basic.domain.order.TrsnHeader;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.mapper.core.oqc.OqcInspDtlMapper;
import com.wzdigit.wms.basic.service.code.GoodsVersionService;
import com.wzdigit.wms.basic.service.code.InventoryService;
import com.wzdigit.wms.basic.service.code.LotnoService;
import com.wzdigit.wms.basic.util.common.CommonString;
import com.wzdigit.wms.basic.util.common.SeparatorString;
import com.wzdigit.wms.wms.service.order.TrsnService;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 
 * 翻拍-判检执行【判检单明细处理】
 * @author Administrator
 *
 */
@Service
@Slf4j
public class OqcDtlNewTaskService {

    @Autowired
    private OqcInspDtlMapper oqcInspDtlMapper;

    @Autowired
    private InventoryService inventoryService;
    
    @Autowired
    private GoodsService goodsService;
    
    @Autowired
    private GoodsVersionService goodsVersionService;

    @Autowired
    private LotnoService lotnoService;
    
    @Autowired
    private TrsnService trsnService;

    @Reference(version = "${dubbo.consumers.basic.simple.code.rule.api:1.0.0}", check = false)
    private BasicSimpleCodeRuleApi basicSimpleCodeRuleApi;
    
    private static final String NOTE_NO = "TRSN_ORDER";
    
    // 嵌套事务
    /**
     * @param inspResult	判检结果
     * @param oqcInspDtl	送检单明细行
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.NESTED)
	public GoodsVersion execute(Integer inspResult, OqcInspDtlDto oqcInspDtl) throws Exception {
    	Date date = new Date();
    	GoodsVersion goods = goodsVersionService.selectBySn(oqcInspDtl.getGoodsSn());
    	goods.setVersion(oqcInspDtl.getVersion());	// 条码数据版本
    	
        // 扣减库存【原来QA状态库存】
        UpdateInventoryInputDto oldInv = new UpdateInventoryInputDto();
        oldInv.setLocId(goods.getLocId());
        oldInv.setQty(goods.getQty().negate());
        oldInv.setPreInQty(BigDecimal.ZERO);
        oldInv.setPreOutQty(BigDecimal.ZERO);
        oldInv.setHoldQty(BigDecimal.ZERO);
        oldInv.setAlocQty(BigDecimal.ZERO);
        oldInv.setPreAlocQty(BigDecimal.ZERO);
        oldInv.setOperator(CommonString.DEFAULT_USER_NAME);
        oldInv.setWhsId(goods.getWhsId());
        oldInv.setOwner(goods.getOwner());
        oldInv.setSkuId(goods.getSkuId());
        oldInv.setFactory(goods.getFactory());
        oldInv.setVendorId(goods.getVendorId());
        oldInv.setLotNo(goods.getLotno());
        oldInv.setInvAttr(goods.getInvAttr());
        oldInv.setQaStatus(goods.getQaStatus());
        oldInv.setUnit(goods.getUnit());
        oldInv.setOperator(CommonString.DEFAULT_USER_NAME);
        
        // 库存日志【原来QA状态库存】
        InvTrans oldInvLog = new InvTrans();
        oldInvLog.setOpCode(OpCodeEnum.INSPECTIONRESULT.getDescription());
        oldInvLog.setDocType(SeparatorString.BLANK_SPACE);
        oldInvLog.setDocNo(SeparatorString.BLANK_SPACE);
        oldInvLog.setDocLineNo(SeparatorString.BLANK_SPACE);
        oldInvLog.setTrsnNo(SeparatorString.BLANK_SPACE);
        oldInvLog.setTrsnLineNo(SeparatorString.BLANK_SPACE);
        oldInvLog.setStatus(InvTransStatusEnum.FINISHED.getCode());
        oldInvLog.setTransTime(date);
        oldInvLog.setOperator(CommonString.DEFAULT_USER_NAME);
        oldInvLog.setTransQty(oldInv.getQty());
        oldInvLog.setCreateTime(date);
        oldInvLog.setCreateUser(CommonString.DEFAULT_USER_NAME);
        
        // 扣减库存
        inventoryService.inventoryOut(oldInv, oldInvLog);
        
        // 新增库存凭证
        insertTrsn(goods, oqcInspDtl.getAsnNo(), oqcInspDtl.getAsnLineNo(), -1, date);
        
        
        // --------------------------------------------//
        // 更新货品清单的QA状态
        String oldGoodsJsonStr = JSON.toJSONString(goods);	//原先的json
        goods.setQaStatus(inspResult);
        goods.setModifyTime(date);
        goods.setModifyUser(CommonString.DEFAULT_USER_NAME);
        goodsVersionService.updateById(goods);
        String newGoodsJsonStr = JSON.toJSONString(goods);	//更新后的json
        
        // 新增货品清单的日志
        GoodsLog goodsLog = new GoodsLog();
        goodsLog.setGoodsSn(goods.getGoodsSn());
        goodsLog.setOpCode("翻牌" + goods.getGoodsSn());
        goodsLog.setReason("变更品质状态");
        goodsLog.setOperator("定时任务-产品判检");
        goodsLog.setUpdateContent("未更新的：" + oldGoodsJsonStr + ",更新后的：" + newGoodsJsonStr);
        goodsLog.setCreateUser(CommonString.DEFAULT_USER_NAME);
        goodsLog.setCreateTime(date);
        goodsService.insertGoodsLog(goodsLog);
        // --------------------------------------------//
        
        
        // 增加库存【判检后新的QA状态库存】
        UpdateInventoryInputDto newInv = new UpdateInventoryInputDto();
        BeanUtil.copyNonNull(oldInv, newInv);
        newInv.setQty(goods.getQty());
        newInv.setQaStatus(goods.getQaStatus());
        
        // 库存日志【判检后新的QA状态库存】
        InvTrans newInvLog = new InvTrans();
        BeanUtil.copyNonNull(oldInvLog, newInvLog);
        oldInvLog.setTransQty(newInv.getQty());
        
        // 增加库存
        inventoryService.inventoryIn(newInv, newInvLog);
        
        // 新增库存凭证
        insertTrsn(goods, oqcInspDtl.getAsnNo(), oqcInspDtl.getAsnLineNo(), 1, date);
        
        // 更新送检单明细状态
        oqcInspDtlMapper.updateStatusById(oqcInspDtl.getOqcInspDtlId(), OqcInspDtlStatusEnum.OQCDTL_STATUS_AFTER_HANDLE.getCode());
        return goods;
    }
	
	/**
     * 新增库存凭证
     * 
     * @param goods
     * @param asnNo
     * @param asnLineNo
     * @param invUpdateFlag
     * @param date
     * @throws Exception
     */
    private void insertTrsn(GoodsVersion goods, String asnNo, String asnLineNo, int invUpdateFlag, Date date) throws Exception {
        // 生成凭证号
        String noteNo = basicSimpleCodeRuleApi.GenerateCode(NOTE_NO);
        // 凭证表头
        TrsnHeader trsnHeader = new TrsnHeader();
        trsnHeader.setNoteNo(noteNo);
        trsnHeader.setNoteType(TrsnNoteTypeEnum.DRAW.getCode());	// 翻牌
        trsnHeader.setFmDoc(asnNo);
        trsnHeader.setWhsId(goods.getWhsId());
        trsnHeader.setOwner(goods.getOwner());
        trsnHeader.setFactory(goods.getFactory());
        trsnHeader.setVendorId(goods.getVendorId());
        trsnHeader.setFmDoc(SeparatorString.RIGHT_SLASH);
        trsnHeader.setDocRef1(SeparatorString.RIGHT_SLASH);
        trsnHeader.setDocRef2(SeparatorString.RIGHT_SLASH);
        trsnHeader.setDocRef3(SeparatorString.RIGHT_SLASH);
        trsnHeader.setDocRef4(SeparatorString.RIGHT_SLASH);
        trsnHeader.setDocRef5(SeparatorString.RIGHT_SLASH);
        trsnHeader.setComments(SeparatorString.RIGHT_SLASH);
        trsnHeader.setStatus(TrsnHeaderStatusEnum.CMP.code);
        trsnHeader.setCreateUser(CommonString.DEFAULT_USER_NAME);
        trsnHeader.setCreateTime(date);
        
        // 凭证明细
        TrsnDtl trsnDtl = new TrsnDtl();
        trsnDtl.setNoteNo(noteNo);
        trsnDtl.setTrsnHeaderId(trsnHeader.getTrsnHeaderId());
        trsnDtl.setFmDoc(asnNo);
        trsnDtl.setFmDocLine(asnLineNo);
        trsnDtl.setQaStatus(goods.getQaStatus());
        trsnDtl.setSkuId(goods.getSkuId());
        trsnDtl.setQty(goods.getQty());
        trsnDtl.setUnit(goods.getUnit());
        trsnDtl.setInvUpdateFlag(invUpdateFlag);
        trsnDtl.setNoteLineNo("1");
        trsnDtl.setInvType("X");
        trsnDtl.setStatus(TrsnDtlStatusEnum.CMP.code);
        trsnDtl.setComments(SeparatorString.RIGHT_SLASH);
        trsnDtl.setCreateUser(CommonString.DEFAULT_USER_NAME);
        trsnDtl.setCreateTime(date);
        if (goods.getLotno() != null) {
        	Lotno lotno = lotnoService.selectByLotno(goods.getLotno());
        	if (lotno != null) {
        		trsnDtl.setLotAttr1(lotno.getLotAttr1());
        		trsnDtl.setLotAttr2(lotno.getLotAttr2());
        		trsnDtl.setLotAttr3(lotno.getLotAttr3());
        		trsnDtl.setLotAttr4(lotno.getLotAttr4());
        		trsnDtl.setLotAttr5(lotno.getLotAttr5());
        		trsnDtl.setLotAttr6(lotno.getLotAttr6());
        		trsnDtl.setLotAttr7(lotno.getLotAttr7());
        		trsnDtl.setLotAttr8(lotno.getLotAttr8());
        		trsnDtl.setLotAttr9(lotno.getLotAttr9());
        		trsnDtl.setLotAttr10(lotno.getLotAttr10());
        		trsnDtl.setLotAttr11(lotno.getLotAttr11());
        		trsnDtl.setLotAttr12(lotno.getLotAttr12());
            }
        }
        
        // 凭证明细-goods
        TrsnDtlGoods trsnDtlGoods = new TrsnDtlGoods();
        trsnDtlGoods.setTrsnDtlId(trsnDtl.getTrsnDtlId());
        trsnDtlGoods.setQaStatus(goods.getQaStatus());
        trsnDtlGoods.setGoodsId(goods.getGoodsId());
        trsnDtlGoods.setGoodsSn(goods.getGoodsSn());
        trsnDtlGoods.setQty(goods.getQty());
        trsnDtlGoods.setStatus(TrsnDtlGoodsStatusEnum.RECEIVED.getCode());
        trsnDtlGoods.setCreateUser(CommonString.DEFAULT_USER_NAME);
        trsnDtlGoods.setCreateTime(date);
        
        // goods-list
        List<TrsnDtlGoods> trsnDtlGoodsList = new ArrayList<>(1);
        trsnDtlGoodsList.add(trsnDtlGoods);
        
        // dtl-one
        TrsnDtlDto trsnDtlDto = new TrsnDtlDto();
        trsnDtlDto.setTrsnDtl(trsnDtl);
        trsnDtlDto.setTrsnDtlGoodsList(trsnDtlGoodsList);
        
        // dtl-list
        List<TrsnDtlDto> trsnDtlDtos = new ArrayList<>(1);
        trsnDtlDtos.add(trsnDtlDto);
        
        TrsnDto trsnDto = new TrsnDto();
        trsnDto.setTrsnHeader(trsnHeader);
        trsnDto.setTrsnDtlDtoList(trsnDtlDtos);
        trsnService.addNewOne(trsnDto);
    }
}
